﻿using System;

namespace SqueezeboxLib
{
    /// <summary>
    /// Represents a Squeezebox Database
    /// </summary>
    public class SqueezeboxDatabase
    {
        public enum RescanMode
        {
            /// <summary>
            /// Rescan the entire music library.
            /// </summary>
            All,

            /// <summary>
            /// Rescan only the playlist directory.
            /// </summary>
            Playlists,

            /// <summary>
            /// Query if scanning.
            /// </summary>
            Query
        }

        public enum RescanAccepetedTaggedParameters
        {
            /// <summary>
            /// Character set to use to return data.
            /// </summary>
            CharSet
        }

        public enum RescanReturnedTaggedParameters
        {
            /// <summary>
            /// Returned with value 1 if the server is still scanning the database, 
            /// otherwise returned with value 0 and the fields below are not returned.
            /// </summary>
            rescan,

            /// <summary>
            /// Total elapsed time since the start of the scan, format "hh:mm:ss".
            /// </summary>
            totaltime,

            /// <summary>
            /// A completion percentage for each importer. 
            /// Importers include "directory" (Music folder), "playlist"(Playlist folder), "iTunes" (iTunes), "musicip" (MusicIP), 
            /// as well as more technical ones such as "mergeva" (Various Artists merging) and "dboptimize" (Database optimization). 
            /// <para>
            /// The type, quantity and order of importers is determined dynamically as rescan progresses.
            /// </para>
            /// </summary>
            importer,

            /// <summary>
            /// Additional information about the current scanning step, like eg. the currently scanned file name.
            /// </summary>
            info,

            /// <summary>
            /// Scanning steps in the order they've been executed.
            /// </summary>
            steps,

            /// <summary>
            /// Information about a possible failure in case a scan has not finished in an attended manner.
            /// </summary>
            lastscanfailed
        }

        public Action<string> Send;

        public EventHandler<MessageReceivedEventArgs> MessageRecieved;

        public SqueezeboxDatabase(Action<string> send, EventHandler<MessageReceivedEventArgs> messageRecieved)
        {
            Send = send;
            MessageRecieved = messageRecieved;
        }

        /// <summary>
        /// Causes Squeezebox Server rescan music libraries, reloading the music file information.
        /// </summary>
        /// <param name="mode"></param>
        public void Rescan(RescanMode mode)
        {
            string command = "rescan";

            switch (mode)
            {
                case RescanMode.All:
                    break;
                case RescanMode.Playlists:
                    command += " playlists";
                    break;
                case RescanMode.Query:
                    command += " ?";
                    break;
                default:
                    break;
            }

            Send(command);
        }

        /// <summary>
        /// Query details on the scanning progress.
        /// </summary>
        public void RescanProgress()
        {
            Send("rescanprogress");
        }

        /// <summary>
        /// Causes Squeezebox Server to cancel a running scan. 
        /// Please note that after stopping a scan this way you'll have to fully rescan your music collection to get consistent data.
        /// </summary>
        public void AbortScan()
        {
            Send("abortscan");
        }

        /// <summary>
        /// Have the Squeezebox Server rescan its music library, reloading the music file information. 
        /// This differs from the "Rescan" method in that it first clears the tag database. 
        /// During a rescan triggered by "WipeCache", "Rescan(RescanMode.Query)" returns true.
        /// </summary>
        public void WipeCache()
        {
            Send("wipecache");
        }

        /// <summary>
        /// Query the number of unique genres in the server music database.
        /// </summary>
        public void InfoTotalGeneres()
        {
            Send("info total genres ?");
        }

        /// <summary>
        /// Query the number of unique artists in the server music database. 
        /// The "Composer, band and orchestra in artists" preference (Server Settings, Behavior) determines which contributors are considered artists.
        /// </summary>
        public void InfoTotalArtists()
        {
            Send("info total artists ?");
        }

        /// <summary>
        /// Query the number of unique albums in the server music database.
        /// </summary>
        public void InfoTotalAlbums()
        {
            Send("info total albums ?");
        }

        /// <summary>
        /// Query the number of unique songs in the server music database.
        /// </summary>
        public void InfoTotalSongs()
        {
            Send("info total songs ?");
        }

        /// <summary>
        /// Query all genres known by the server.
        /// <para>
        /// Note that the server supports multiple genres per track,
        /// depending on the "Multiple items in tags" preference (Server Settings, Behavior).
        /// </para>
        /// </summary>
        /// <param name="start"></param>
        /// <param name="itemsPerResponse"></param>
        /// <param name="taggedParameters"></param>
        public void Generes(int start, int itemsPerResponse, params GeneresTaggedParameter[] taggedParameters)
        {
            Send("generes " + start + " " + itemsPerResponse + " " + string.Join<GeneresTaggedParameter>(" ", taggedParameters));
        }


        public void Artists(int start, int itemsPerResponse, params ArtistsTaggedParameter[] taggedParameters)
        {

        }

        public void Albums()
        {
            throw new NotImplementedException();
        }

        public void Years()
        {
            throw new NotImplementedException();
        }

        public void MusicFolder()
        {
            throw new NotImplementedException();
        }

        public void Playlists()
        {
            throw new NotImplementedException();
        }

        public void PlaylistsTracks()
        {
            throw new NotImplementedException();
        }

        public void PlaylistsNew()
        {
            throw new NotImplementedException();
        }

        public void PlaylistsRewname()
        {
            throw new NotImplementedException();
        }

        public void PlaylistsDelete()
        {
            throw new NotImplementedException();
        }

        public void PlaylistsEdit()
        {
            throw new NotImplementedException();
        }

        public void SongInfo()
        {
            throw new NotImplementedException();
        }

        public void Titles()
        {
            throw new NotImplementedException();
        }

        public void Search()
        {
            throw new NotImplementedException();
        }
    }
}
